package com.andy.springboot.utils;

import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ase加解密工具
 * @author Andy.ye
 * @date 2018年3月23日 下午3:30:01
 */
public class AesUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(AesUtil.class);

	/**
	 * aes加密
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 * @throws EncryptionException
	 */
	public static String aesEncrypt(String data, String key) {
		try {
			if (StringUtils.isBlank(data)) {
				throw new Exception("data为空，无法加密！");
			}
			if (StringUtils.isBlank(key)) {
				throw new Exception("aseKey为空，无法加密！");
			}
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			SecretKeySpec keyspec = new SecretKeySpec(toByte(key), "AES");
			cipher.init(Cipher.ENCRYPT_MODE, keyspec);
			byte[] encrypted = cipher.doFinal(data.getBytes());
			return toHex(encrypted);
		} catch (Exception e) {
			LOGGER.error("加密失败！", e);
		}
		return null;
	}

	/**
	 * aes解密
	 * @param data
	 * @param key
	 * @return
	 * @throws DecryptionException
	 */
	public static String aesDecrypt(String data, String key) {
		try {
			if (StringUtils.isBlank(data)) {
				throw new Exception("data为空，无法解密！");
			}
			if (StringUtils.isBlank(key)) {
				throw new Exception("aseKey为空，无法解密！");
			}
			byte[] encrypted1 = toByte(data);
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			SecretKeySpec keyspec = new SecretKeySpec(toByte(key), "AES");
			cipher.init(Cipher.DECRYPT_MODE, keyspec);
			byte[] original = cipher.doFinal(encrypted1);
			return new String(original, "UTF-8");
		} catch (Exception e) {
			LOGGER.error("解密失败！", e);
		}
		return null;
	}

	/**
	 * 16进制字符串转字节数组
	 * @param hexString 16进制字符串
	 * @return 转化后的字节数组
	 */
	public static byte[] toByte(String hexString) {
		int len = hexString.length() / 2;
		byte[] result = new byte[len];
		for (int i = 0; i < len; i++) {
			result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
		}
		return result;
	}

	static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	/**
	 * @param s
	 * @return md5 in lower case
	 */
	public final static String md5(String s) {
		if (StringUtils.isBlank(s)) {
			return "";
		}
		try {
			byte[] btInput = s.getBytes();
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			// 使用指定的字节更新摘要
			mdInst.update(btInput);
			// 获得密文
			byte[] md = mdInst.digest();
			// 把密文转换成十六进制的字符串形式
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			return s;
		}
	}

	/**
	 * 字节数组转16进制字符串
	 * @param buf 字节数组
	 * @return 转化后的字符串
	 */
	private static String toHex(byte[] buf) {
		if (buf == null)
			return "";
		StringBuffer result = new StringBuffer(2 * buf.length);
		for (int i = 0; i < buf.length; i++) {
			appendHex(result, buf[i]);
		}
		return result.toString();
	}

	private final static String HEX = "0123456789abcdef";

	private static void appendHex(StringBuffer sb, byte b) {
		sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
	}
}
